package com.idealighter.game.common;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;

import com.idealighter.game.core.assertions.HuohuaAssert;
import com.idealighter.game.core.error.ErrorCode;
import com.idealighter.game.message.core.ResMessage;
import com.idealighter.game.player.struct.Player;
import com.idealighter.game.tool.sts.message.ResStsTokenMsg;

import java.text.MessageFormat;
import java.util.Date;

import lombok.extern.slf4j.Slf4j;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

@Singleton
@Slf4j
public class OssMsgMgr {

  private static final String STS_ENDPOINT = "sts.aliyuncs.com";

  private final String endPoint;
  private final String roleArn;
  private final String accessKeyId;
  private final String accessKeySecret;
  private final String roleSessionNamePrefix;

  private final String bucket;

  private static final String POLICY_TEMPLE =
      "'{'\"Statement\": ['{'\"Action\": [\"oss:Get*\",\"oss:List*\"],\"Effect\": \"Allow\","
          + "\"Resource\": [\"acs:oss:*:*:{0}/*\",\"acs:oss:*:*:{0}\"]  '}',"
          + "'{'\"Action\":[\"oss:PutObject\"],\"Effect\":\"Allow\","
          + "\"Resource\":[\"acs:oss:*:*:{0}/avatar/{1}/*\","
          + "\"acs:oss:*:*:{0}/voice/{1}/*\"],\"Version\":\"1\"'}']'}'";

  /**
   * 构造函数.
   * 
   * @param endPoint .
   * @param roleArn .
   * @param accessKeyId .
   * @param accessKeySecret .
   * @param bucket .
   * @param roleSessionNamePrefix .
   */
  @Inject
  public OssMsgMgr(@Named("oss.endPoint") String endPoint, @Named("oss.roleArn") String roleArn,
      @Named("oss.accessKeyId") String accessKeyId,
      @Named("oss.accessKeySecret") String accessKeySecret, @Named("oss.bucket") String bucket,
      @Named("oss.roleSessionNamePrefix") String roleSessionNamePrefix) {
    this.endPoint = endPoint;
    this.roleArn = roleArn;
    this.accessKeyId = accessKeyId;
    this.accessKeySecret = accessKeySecret;
    this.bucket = bucket;
    this.roleSessionNamePrefix = roleSessionNamePrefix;
  }


  /**
   * 生成osstoken .
   *
   * @author abin
   * @date 2018年5月23日 下午4:11:43
   * @param player 玩家.
   * @return 结果.
   */
  public ResMessage generateOssToken(Player player) {
    ResStsTokenMsg msg = new ResStsTokenMsg();
    try {
      // Init ACS Client
      DefaultProfile.addEndpoint("", "", "Sts", STS_ENDPOINT);
      IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret);
      DefaultAcsClient client = new DefaultAcsClient(profile);
      final AssumeRoleRequest request = new AssumeRoleRequest();
      request.setMethod(MethodType.POST);
      request.setRoleArn(roleArn);
      request.setRoleSessionName(roleSessionNamePrefix + player.getId());
      request
          .setPolicy(MessageFormat.format(POLICY_TEMPLE, bucket, String.valueOf(player.getId())));
      request.setDurationSeconds(3600L);
      final AssumeRoleResponse response = client.getAcsResponse(request);

      msg.setAccessKeyId(response.getCredentials().getAccessKeyId());
      msg.setAccessKeySecret(response.getCredentials().getAccessKeySecret());
      msg.setBucket(bucket);
      msg.setEndPoint(endPoint);
      msg.setSecurityToken(response.getCredentials().getSecurityToken());

      Date date = parse(response.getCredentials().getExpiration(), "yyyy-MM-dd'T'HH:mm:ss'Z'");
      msg.setExpiration(date.getTime());
      //
      // System.out.println("Expiration: " + response.getCredentials().getExpiration());
      // System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
      // System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
      // System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
      // System.out.println("RequestId: " + response.getRequestId());
    } catch (ClientException exception) {
      log.error("获取 sts 授权token 失败 ", exception);
      HuohuaAssert.isTrue(false, ErrorCode.GETTOKEN_FAIL);
    }

    return msg;

  }

  /**
   * pase utc 时间.
   *
   * @author abin
   * @date 2018年5月26日 上午10:44:12
   * @param date 日期.
   * @param fmt 格式化.
   * @return 日期.
   */
  private static Date parse(String date, String fmt) {
    if (date == null) {
      throw new NullPointerException();
    }
    DateTimeFormatter dfmt = DateTimeFormat.forPattern(fmt).withZone(DateTimeZone.UTC);
    DateTime dateTime = DateTime.parse(date, dfmt);
    return dateTime.toDate();
  }

  /**
   * test .
   *
   * @author abin
   * @date 2018年5月23日 下午4:12:29
   * @param args args.
   */
  public static void main(String[] args) {
    try {


      DefaultProfile.addEndpoint("", "", "Sts", STS_ENDPOINT);

      final AssumeRoleRequest request = new AssumeRoleRequest();

      request.setMethod(MethodType.POST);
      request.setRoleArn("acs:ram::1383897030912141:role/aliyunosstokengeneratorrole");
      request.setRoleSessionName("roomcard-1");
      request.setDurationSeconds(3600L);
      System.out.println(POLICY_TEMPLE);
      System.out.println(MessageFormat.format(POLICY_TEMPLE, "hh-roomcard", "1008292"));
      request.setPolicy(MessageFormat.format(POLICY_TEMPLE, "hh-roomcard", "1008292"));
      IClientProfile profile =
          DefaultProfile.getProfile("", "LTAIvAyfPe2fdeT6", "ecx1jBIYiQHDyEY9sguG13Y5MJ8cc8");

      DefaultAcsClient client = new DefaultAcsClient(profile);
      final AssumeRoleResponse response = client.getAcsResponse(request);

      System.out.println(client.toString());
      // Date date = TimeUtil.yyyyMMdd_HHmmss(response.getCredentials().getExpiration());
      // System.out.println(date);
      System.out.println("Expiration: " + response.getCredentials().getExpiration());
      System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
      System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
      System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
      System.out.println("RequestId: " + response.getRequestId());
      Date date = parse(response.getCredentials().getExpiration(), "yyyy-MM-dd'T'HH:mm:ss'Z'");

      System.out.println(date);

      // OSSClient ossClient =
      // new OSSClient("oss-cn-shenzhen.aliyuncs.com", response.getCredentials().getAccessKeyId(),
      // response.getCredentials().getAccessKeySecret(),
      // response.getCredentials().getSecurityToken());
      //
      // // 上传字符串
      // String content = "Hello OSS";
      // ossClient.putObject("hh-roomcard", "avatar/1008292/123",
      // new ByteArrayInputStream(content.getBytes()));
      // // 关闭client
      // ossClient.shutdown();

    } catch (ClientException exception) {
      log.error("获取 sts 授权token 失败 ", exception);
    }
  }
}
